﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using WMM.Tapioca.Utilities;

namespace WMM.Tapioca.Formula.Aspects
{
    /// <summary>
    /// A typed dimension rule is an aspect rule for a typed dimension aspect that 
    /// is expressed by the <formula:typedDimension> element. 
    /// </summary>
    public class TypedDimensionAspect : DimensionAspect
    {
        private XElement element;

        internal XElement Element
        {
            get { return element; }
            set { element = value; }
        }

        private string xpath;

        /// <returns> An XPath expression that, when evaluated, MUST yield a sequence containing a 
        /// single element node. This element node (and its descendants, if any) are the content 
        /// of the root element of the typed dimension value for the output fact.  </returns>
        internal string Xpath
        {
            get { return xpath; }
            set { xpath = value; }
        }

        private XElement value;

        /// <returns> That single child element of the <formula:value> element and the child element of the 
        /// typed dimension value of the output fact MUST be corresponding elements.  </returns>
        public XElement Value
        {
            get { return this.value; }
            set { this.value = value; }
        }

        private string omit;

        /// <returns> If an explicit dimension rule contains a <formula:omit> element then the dimension
        /// identified by the explicit dimension rule MUST NOT have a value for the output fact. . </returns>
        internal string Omit
        {
            get { return omit; }
            set { omit = value; }
        }

        /// <summary>
        /// Constructor.
        /// </summary>
        public TypedDimensionAspect(XElement typedDimensionAspect, FormulaXBRL formulaXbrl)
        {
            XNamespace formula = Constants.FORMULA;

            this.Element = typedDimensionAspect;

            XElement aspect = typedDimensionAspect.Parent;

            if (aspect.Attribute("source") != null)
            {
                this.Source = aspect.Attribute("source").Value;
            }

            if (typedDimensionAspect.Attribute("source") != null)
            {
                this.Source = typedDimensionAspect.Attribute("source").Value;
            }

            if (typedDimensionAspect.Attribute("dimension") != null)
            {
                this.Dimension = typedDimensionAspect.Attribute("dimension").Value;
            }

            XElement xpath = typedDimensionAspect.Element(formula + "xpath");

            if (xpath != null)
            {
                this.Xpath = xpath.Value;
            }

            XElement value = typedDimensionAspect.Element(formula + "value");

            if (value != null)
            {
                this.Value = value.Elements().FirstOrDefault();
            }

            XElement omit = typedDimensionAspect.Element(formula + "omit");

            if (omit != null)
            {
                this.Omit = omit.Name.LocalName;
            }

            formulaXbrl.TypedDimensionAspectFormulas.Add(this);
        }
    }

}
